package com.eoekun.dashboard.contoller;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.eoekun.dashboard.dao.dataobject.Dashboard;
import com.eoekun.dashboard.dao.mapper.DashboardMapperExt;
import com.eoekun.dashboard.model.PageVO;
import com.eoekun.dashboard.model.Result;
import com.eoekun.dashboard.model.ResultCode;
import com.eoekun.dashboard.model.vo.DashboardQueryVO;
import com.eoekun.dashboard.model.vo.DashboardVO;
import com.eoekun.dashboard.util.ExcelUtil;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

@RestController()
@RequestMapping("/dashboard/")
public class ProjectController {

    private static final Logger log = LoggerFactory.getLogger(ProjectController.class);
    @Resource
    private DashboardMapperExt dashboardMapper;

    @RequestMapping("load")
    public Result<PageVO<DashboardVO>> load(DashboardQueryVO dashboardParam) {
        if (null == dashboardParam) {
            dashboardParam = new DashboardQueryVO();
        }
        List<String> applications = dashboardParam.getApplications();
        if (null != applications) {
            Set<String> applications2 = new HashSet<>();
            for (int i = 0; i < applications.size(); i++) {
                String application = applications.get(i);
                List<String> radomStr = getList(application, applications);
                applications2.addAll(radomStr);
            }
            applications2.addAll(applications);
            List<String> applicationFinal = new ArrayList<String>();
            applicationFinal.addAll(applications2);
            dashboardParam.setApplications(applicationFinal);
        }
        dashboardParam.setIsDeleted(0);
        dashboardParam.setOrderByClause("status,task_id desc");
        List<Dashboard> data = dashboardMapper.queryPageExt(dashboardParam);
        Long count = dashboardMapper.queryCountExt(dashboardParam);
        List<DashboardVO> list = new ArrayList<>();
        for (Dashboard dashboard : data) {
            JSON json = (JSON) JSON.toJSON(dashboard);
            DashboardVO d = JSON.toJavaObject(json, DashboardVO.class);
            List<String> developers = transStr2List(dashboard.getDeveloper());
            d.setDevelopers(developers);
            List<String> testerses = transStr2List(dashboard.getTesters());
            d.setTesterses(testerses);
            List<String> applications2 = transStr2List(dashboard.getApplication());
            d.setApplications(applications2);
            list.add(d);
        }
        PageVO<DashboardVO> pageVO = new PageVO<>(list, count);
        return new Result<>(pageVO);
    }

    @RequestMapping("update")
    public Result<Void> update(@RequestBody DashboardVO dashboardVO) {
        if (null == dashboardVO) {
            return new Result<>(ResultCode.PARAM_NOT_EMPTY);
        }
        JSON json = (JSON) JSON.toJSON(dashboardVO);
        Dashboard dashboardParam = JSON.toJavaObject(json, Dashboard.class);
        Long taskId = dashboardParam.getTaskId();
        if (null == taskId) {
            return new Result<>(ResultCode.PARAM_NOT_EMPTY, "id为空");
        }
        String name = dashboardParam.getForceNullField();
        if ("developers".equals(name)) {
            name = "developer";
        }
        if ("testerses".equals(name)) {
            name = "testers";
        }
        if ("applications".equals(name)) {
            name = "application";
        }
        if (null != dashboardVO.getDevelopers()) {
            String developer = StringUtils.join(dashboardVO.getDevelopers(), ",");
            dashboardParam.setDeveloper(developer);
        }
        if (null != dashboardVO.getTesterses()) {
            String testers = StringUtils.join(dashboardVO.getTesterses(), ",");
            dashboardParam.setTesters(testers);
        }
        if (null != dashboardVO.getApplications()) {
            String application = StringUtils.join(dashboardVO.getApplications(), ",");
            dashboardParam.setApplication(application);
        }
        log.info("update Dashboard,dashboardParam:{}", dashboardParam);
        dashboardParam.setUpdateTime(new Date());
        Integer updated = dashboardMapper.updateByPrimaryKeySelective(dashboardParam);
        if (null != dashboardParam.getForceNullField()) {
            Dashboard record = dashboardMapper.selectByPrimaryKey(taskId);
            try {
                Field field = Dashboard.class.getDeclaredField(name);
                field.setAccessible(true);
                field.set(record, null);
                dashboardMapper.updateByPrimaryKey(record);
            } catch (Exception e) {
                log.error("update forcenull field fail,{}", dashboardParam, e);
            }
        }
        log.info("update Dashboard,return:{}", updated);
        return new Result<>(ResultCode.SUCCESS);
    }

    @RequestMapping("add")
    public Result<Void> add(@RequestBody DashboardVO dashboardParam) {
        if (null == dashboardParam) {
            return new Result<>(ResultCode.PARAM_NOT_EMPTY);
        }
        if (null != dashboardParam.getTaskId()) {
            dashboardParam.setTaskId(null);
        }
        log.info("insertSelective Dashboard,dashboardParam:{}", dashboardParam);
        dashboardParam.setCreateTime(new Date());
        dashboardParam.setUpdateTime(null);
        dashboardParam.setTaskId(null);
        if (null == dashboardParam.getMonth()) {
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
            Integer month = Integer.parseInt(sdf.format(d));
            dashboardParam.setMonth(month);
        }
        if (null != dashboardParam.getDevelopers()) {
            dashboardParam.setDeveloper(StringUtils.join(dashboardParam.getDevelopers(), ','));
        }
        if (null != dashboardParam.getTesterses()) {
            dashboardParam.setTesters(StringUtils.join(dashboardParam.getTesterses(), ','));
        }
        Integer updated = dashboardMapper.insertSelective(dashboardParam);
        log.info("insertSelective Dashboard,return:{}", updated);
        return new Result<>(ResultCode.SUCCESS);
    }

    @RequestMapping("delete")
    public Result<Void> delete(@RequestParam Long taskId) {
        log.info("delete Dashboard,taskId:{}", taskId);
        Dashboard record = new Dashboard();
        record.setTaskId(taskId);
        record.setIsDeleted(1);
        int updated = dashboardMapper.updateByPrimaryKeySelective(record);
        log.info("delete Dashboard,return:{}", updated);
        return new Result<>(ResultCode.SUCCESS);
    }

    @RequestMapping("exportExcel")
    @SuppressWarnings({"rawtypes", "unchecked"})
    public void exportExcel(int exportType, String columndatas, String queryParams,
            HttpServletRequest request, HttpServletResponse response) {
        JSON.DEFFAULT_DATE_FORMAT = "yyyy/MM/dd";
        log.info("导出数据记录,exportType:" + exportType);
        List<DashboardVO> fileInfoJsons = null;
        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.setDateFormat("yyyy-MM-dd HH:mm:ss");
        Gson gson = gsonBuilder.create();
        Map<String, String> queryMap =
                gson.fromJson(queryParams, new TypeToken<Map<String, String>>() {}.getType());

        String filename = "项目看板";
        if (1 == exportType || 2 == exportType) {
            try {
                fileInfoJsons = JSON.parseArray(columndatas, DashboardVO.class);
                if (1 == exportType) {
                    filename += "第" + queryMap.get("page") + "页记录.xls";
                } else {
                    filename += "选中" + fileInfoJsons.size() + "条记录.xls";
                }
            } catch (Exception e) {
                log.error("项目看板数据导出当前页Excel文件出错:" + e.getMessage());
                throw new RuntimeException("数据解析异常");
            }
            log.debug("项目看板数据导出当页Excel数据数目:" + fileInfoJsons.size());
        } else if (3 == exportType) {
            filename += ".xls";
            DashboardQueryVO dashboardParam = new DashboardQueryVO();
            dashboardParam.setPage(1);
            dashboardParam.setRows(Integer.MAX_VALUE);
            fileInfoJsons = this.load(dashboardParam).getData().getData();
        } else {
            log.debug("项目看板数据导出参数错误:导出类型仅可以为1/2/3");
        }
        if (null == fileInfoJsons || 0 == fileInfoJsons.size()) {
            return;
        }
        List<Map> dataList = new ArrayList<Map>();
        if (3 == exportType) {
            for (Object fileInfoJson : fileInfoJsons) {
                String json =
                        JSON.toJSONString(fileInfoJson, SerializerFeature.WriteDateUseDateFormat);
                Map map = gson.fromJson(json, Map.class);
                dataList.add(map);
            }
        } else {
            for (DashboardVO fileInfoJson : fileInfoJsons) {
                String json =
                        JSON.toJSONString(fileInfoJson, SerializerFeature.WriteDateUseDateFormat);
                Map map = gson.fromJson(json, Map.class);
                dataList.add(map);
            }
        }
        String names =
                "[\"任务名称\",\"任务类: 1. 日常需求 2. 修复 3. 优化\",\"优先级,值越大,优先级越高\",\"是否需要文档: 0. 不需要 1. 需要\",\"设计文档地址\",\"是否需要代码评审: 0. 不需要 1. 需要\",\"jira编号或地址\",\"应用\",\"开发人员\",\"测试人员\",\"工作量,天\",\"计划开发日期\",\"实际开发日期\",\"计划完成日期\",\"实际完成日期\",\"计划测试完成日期\",\"实际测试完成日期\",\"计划上线日期\",\"实际上线日期\",\"备注\",\"是否延期: 0. 未延期 1. 已延期\",\"延期原因\",\"创建人id\",\"创建人姓名\",\"创建时间\",\"修改时间\",\"更新人id\",\"更新人姓名\",\"是否已删除: 0. 未删除 1. 已删除\"]";
        String indexs =
                "[\"taskName\",\"taskType\",\"priority\",\"isNeedDoc\",\"docLink\",\"isNeedReview\",\"jiraId\",\"application\",\"developer\",\"testers\",\"workDays\",\"planStartDate\",\"realStartDate\",\"planEndDate\",\"realEndDate\",\"planTestDate\",\"realTestDate\",\"planOnlieDate\",\"realOnlieDate\",\"remark\",\"isDelay\",\"delayReason\",\"userId\",\"username\",\"createTime\",\"updateTime\",\"updateUserId\",\"updateUsername\",\"isDeleted\"]";

        List<String> fieldNameList = gson.fromJson(names, List.class);
        List<String> fieldIndexList = gson.fromJson(indexs, List.class);
        ExcelUtil.exportJXLWorkbook(fieldNameList, fieldIndexList, dataList, filename, request,
                response);
    }



    private List<String> getList(String application, List<String> applications) {
        List<String> result = new ArrayList<>();
        for (String application2 : applications) {
            if (!application2.equals(application)) {
                result.add(application + "," + application2);
            }
        }
        return result;
    }

    private static List<String> transStr2List(String developerStr) {
        if (null == developerStr) {
            return new ArrayList<>();
        }
        List<String> list = new ArrayList<>(Arrays.asList(developerStr.split(",")));
        return list;
    }

}
